import type { Point } from '@/types';
import { degreesToRadians } from './coordTransform';

/**
 * 检查点是否在旋转矩形内
 * @param point 要检查的点
 * @param rectCenter 矩形中心
 * @param rectWidth 矩形宽度
 * @param rectHeight 矩形高度
 * @param rotation 旋转角度（度）
 * @returns 是否包含
 */
export function pointInRotatedRect(
    point: Point,
    rectCenter: Point,
    rectWidth: number,
    rectHeight: number,
    rotation: number
): boolean {
    rotation = rotation - 90

    // 将点转换到矩形局部坐标系（以矩形中心为原点）
    const translatedX = point.x - rectCenter.x;
    const translatedY = point.y - rectCenter.y;

    // 将角度转换为弧度
    const rad = degreesToRadians(rotation);

    // 旋转点（使用顺时针旋转矩阵进行逆旋转）
    // 顺时针旋转矩阵与逆时针旋转矩阵的区别在于sin项的符号
    const rotatedX = translatedX * Math.cos(rad) - translatedY * Math.sin(rad);
    const rotatedY = translatedX * Math.sin(rad) + translatedY * Math.cos(rad);

    // 检查旋转后的点是否在轴对齐的矩形内
    const halfWidth = rectWidth / 2;
    const halfHeight = rectHeight / 2;

    return (
        rotatedX >= -halfWidth &&
        rotatedX <= halfWidth &&
        rotatedY >= -halfHeight &&
        rotatedY <= halfHeight
    );
}

/**
 * 检查两个旋转矩形是否碰撞
 * @param rect1 矩形1
 * @param rect2 矩形2
 * @returns 是否碰撞
 */
export function rectanglesCollide(
    rect1: {
        center: Point;
        width: number;
        height: number;
        rotation: number;
    },
    rect2: {
        center: Point;
        width: number;
        height: number;
        rotation: number;
    }
): boolean {
    // 获取两个矩形的所有边
    const rect1Edges = getRectEdges(rect1);
    const rect2Edges = getRectEdges(rect2);

    // 收集所有可能的分离轴（每个边的法线）
    const axes = [
        ...rect1Edges.map(edge => getEdgeNormal(edge)),
        ...rect2Edges.map(edge => getEdgeNormal(edge))
    ];

    // 检查每个轴
    for (const axis of axes) {
        // 投影两个矩形到当前轴
        const rect1Projection = projectRectToAxis(rect1, axis);
        const rect2Projection = projectRectToAxis(rect2, axis);

        // 检查投影是否重叠
        if (!projectionsOverlap(rect1Projection, rect2Projection)) {
            // 找到分离轴，没有碰撞
            return false;
        }
    }

    // 所有轴上都有重叠，发生碰撞
    return true;
}

/**
 * 获取矩形的所有边
 */
function getRectEdges(rect: {
    center: Point;
    width: number;
    height: number;
    rotation: number;
}): Array<{ start: Point; end: Point }> {
    const { center, width, height, rotation } = rect;
    const rad = degreesToRadians(rotation);
    const halfWidth = width / 2;
    const halfHeight = height / 2;

    // 计算矩形的四个顶点
    const corners = [
        rotatePoint({ x: halfWidth, y: halfHeight }, rad),
        rotatePoint({ x: -halfWidth, y: halfHeight }, rad),
        rotatePoint({ x: -halfWidth, y: -halfHeight }, rad),
        rotatePoint({ x: halfWidth, y: -halfHeight }, rad)
    ];

    // 转换到世界坐标系
    const worldCorners = corners.map(corner => ({
        x: corner.x + center.x,
        y: corner.y + center.y
    }));

    // 创建边
    return [
        { start: worldCorners[0], end: worldCorners[1] },
        { start: worldCorners[1], end: worldCorners[2] },
        { start: worldCorners[2], end: worldCorners[3] },
        { start: worldCorners[3], end: worldCorners[0] }
    ];
}

/**
 * 旋转点
 */
function rotatePoint(point: Point, rad: number): Point {
    return {
        x: point.x * Math.cos(rad) - point.y * Math.sin(rad),
        y: point.x * Math.sin(rad) + point.y * Math.cos(rad)
    };
}

/**
 * 获取边的法线（垂直方向）
 */
function getEdgeNormal(edge: { start: Point; end: Point }): Point {
    // 边的方向向量
    const dir = {
        x: edge.end.x - edge.start.x,
        y: edge.end.y - edge.start.y
    };

    // 法线（垂直方向），标准化
    const normal = { x: -dir.y, y: dir.x };
    const length = Math.sqrt(normal.x * normal.x + normal.y * normal.y);

    return {
        x: normal.x / length,
        y: normal.y / length
    };
}

/**
 * 将矩形投影到轴上
 */
function projectRectToAxis(
    rect: {
        center: Point;
        width: number;
        height: number;
        rotation: number;
    },
    axis: Point
): { min: number; max: number } {
    const { center, width, height, rotation } = rect;
    const rad = degreesToRadians(rotation);
    const halfWidth = width / 2;
    const halfHeight = height / 2;

    // 计算矩形的四个顶点
    const corners = [
        rotatePoint({ x: halfWidth, y: halfHeight }, rad),
        rotatePoint({ x: -halfWidth, y: halfHeight }, rad),
        rotatePoint({ x: -halfWidth, y: -halfHeight }, rad),
        rotatePoint({ x: halfWidth, y: -halfHeight }, rad)
    ];

    // 转换到世界坐标系
    const worldCorners = corners.map(corner => ({
        x: corner.x + center.x,
        y: corner.y + center.y
    }));

    // 计算每个顶点在轴上的投影
    const projections = worldCorners.map(corner =>
        corner.x * axis.x + corner.y * axis.y
    );

    // 返回投影的最小值和最大值
    return {
        min: Math.min(...projections),
        max: Math.max(...projections)
    };
}

/**
 * 检查两个投影是否重叠
 */
function projectionsOverlap(
    proj1: { min: number; max: number },
    proj2: { min: number; max: number }
): boolean {
    return !(proj1.max < proj2.min || proj2.max < proj1.min);
}
